#include <jni.h>
#include <string>
#include "SoundTouch.h"

#include <android/log.h>
#define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"soundtouch",FORMAT,##__VA_ARGS__);
#define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR,"soundtouch",FORMAT,##__VA_ARGS__);

soundtouch::SoundTouch *soundTouch = NULL;

extern "C"
JNIEXPORT void JNICALL
Java_com_dream_libsoundtouch_SoundTouch_nativeInit(JNIEnv *env, jobject thiz) {
    soundTouch = new soundtouch::SoundTouch();
}

extern "C"
JNIEXPORT void JNICALL
Java_com_dream_libsoundtouch_SoundTouch_nativeSetSampleRate(JNIEnv *env, jobject thiz,
                                                            jint sample_rate) {
    soundTouch->setSampleRate(sample_rate);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_dream_libsoundtouch_SoundTouch_nativeSetChannels(JNIEnv *env, jobject thiz,
                                                          jint channels) {
    soundTouch->setChannels(channels);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_dream_libsoundtouch_SoundTouch_nativeSetTempoChange(JNIEnv *env, jobject thiz,
                                                             jfloat tempo) {
    soundTouch->setTempo(tempo);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_dream_libsoundtouch_SoundTouch_nativeSetPitchSemiTones(JNIEnv *env, jobject thiz,
                                                                jint pitch) {
    soundTouch->setPitchSemiTones(pitch);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_dream_libsoundtouch_SoundTouch_nativeSetRateChange(JNIEnv *env, jobject thiz,
                                                            jfloat rate) {
    soundTouch->setRate(rate);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_dream_libsoundtouch_SoundTouch_nativePutSamples(JNIEnv *env, jobject thiz,
                                                         jshortArray samples, jint len) {
    jshort *buffer = env->GetShortArrayElements(samples, NULL);
    soundTouch->putSamples(buffer, len);
    env->ReleaseShortArrayElements(samples, buffer, 0);
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_dream_libsoundtouch_SoundTouch_nativeReceiveSamples(JNIEnv *env, jobject thiz,
                                                             jshortArray buffer, jint bufferSize) {

    jshort *jBuffer = env->GetShortArrayElements(buffer, NULL);

    soundtouch::SAMPLETYPE  *cBuffer = (soundtouch::SAMPLETYPE *) malloc(bufferSize * sizeof(soundtouch::SAMPLETYPE));
    int receivedSamples = soundTouch->receiveSamples(cBuffer, bufferSize);
    for (int i = 0; i < receivedSamples; i++) {
        jBuffer[i] = (jshort) cBuffer[i];
    }
    free(cBuffer);
    env->ReleaseShortArrayElements(buffer, jBuffer, 0);
    return receivedSamples;
}

extern "C"
JNIEXPORT void JNICALL
Java_com_dream_libsoundtouch_SoundTouch_nativeFlush(JNIEnv *env, jobject thiz) {
    soundTouch->flush();
}

extern "C"
JNIEXPORT void JNICALL
Java_com_dream_libsoundtouch_SoundTouch_nativeClear(JNIEnv *env, jobject thiz) {
    soundTouch->clear();
}